﻿using Microsoft.VisualStudio.Modeling;
using VsxFactory.Modeling.Strategies;

namespace VsxFactory.Modeling
{
    public static class SynchronizationHelper
    {
        private static string SYNCHRONIZATION_FLAG = "{13E44B8A-65B8-45ec-9F37-C3D3A99ADFFC}";

        /// <summary>
        /// Determines whether the specified store is synchronizing.
        /// </summary>
        /// <param name="store">The store.</param>
        /// <param name="element">The element.</param>
        /// <returns></returns>
        public static CodeGenerationEvent GetSynchronizingStatus(this Store store, ModelElement element)
        {
            object flag;
            if (!store.TransactionManager.InTransaction)
                return CodeGenerationEvent.None;
            Transaction transaction = store.TransactionManager.CurrentTransaction;
            while (transaction != null)
            {
                if (transaction.Context.ContextInfo.TryGetValue(SYNCHRONIZATION_FLAG + element.Id.ToString("B"), out flag))
                    return (CodeGenerationEvent)flag;
                transaction = transaction.Parent;
            }
            return CodeGenerationEvent.None;
        }

        /// <summary>
        /// Determines whether the specified store is synchronizing.
        /// </summary>
        /// <param name="store">The store.</param>
        /// <returns></returns>
        public static CodeGenerationEvent GetSynchronizingStatus(this Store store)
        {
            object flag;
            if (!store.TransactionManager.InTransaction)
                return CodeGenerationEvent.None;
            Transaction transaction = store.TransactionManager.CurrentTransaction;
            while (transaction != null)
            {
                if (transaction.Context.ContextInfo.TryGetValue(SYNCHRONIZATION_FLAG, out flag))
                    return (CodeGenerationEvent)flag;
                transaction = transaction.Parent;
            }
            return CodeGenerationEvent.None;
        }

        /// <summary>
        /// Sets the synchronize transaction.
        /// </summary>
        /// <param name="store">The store.</param>
        /// <param name="element">The element.</param>
        /// <param name="status">The status.</param>
        public static void SetSynchronizeTransaction(this Store store, ModelElement element, CodeGenerationEvent status)
        {
            store.TransactionManager.CurrentTransaction.Context.ContextInfo.Add(SYNCHRONIZATION_FLAG + element.Id.ToString("B"), status);
            SetSynchronizeTransaction(store, status);
        }

        /// <summary>
        /// Sets the synchronize transaction.
        /// </summary>
        /// <param name="store">The store.</param>
        /// <param name="status">The status.</param>
        public static void SetSynchronizeTransaction(this Store store, CodeGenerationEvent status)
        {
            if (GetSynchronizingStatus(store) != CodeGenerationEvent.None)
                store.TransactionManager.CurrentTransaction.Context.ContextInfo.Add(SYNCHRONIZATION_FLAG, status);
        }
    }
}
